package com.cskaoyan.javase.oop2.encapsulate._2polymorphic._3cast;

import javax.swing.*;

/**
 * 引用数据类型的强制类型转换,也就是向下转型
 * 发生的前提: 必须要有继承,必须有父子类
 * 转换的是什么: 转换的是引用的数据类型,向下转型是将父类类型引用转换成子类类型引用
 * 能够通过遍历的条件是什么:
 *      必须使用以下语法:
 *      强转的语法:
 *      强转成子类类型 对象名 = (强转成子类类型)被强转的父类引用;
 *      其次,
 *      强转前的类型和强转后的类型必须是一条继承链中的两个父子类
 *
 * (重点)
 * 能够正常运行,能够强转成功的前提是什么?
 * 强转一旦失败,就会导致ClassCastException异常产生,程序终止
 * 强转的本质是,让一个"在编译器看来是父类类型的对象"去做"子类对象"的事情
 * 这个强转要想成功
 * 前提是那个"在编译器看来是父类类型的对象"真的能够去做"子类对象的事情"
 * 也就是说那个"在编译器看来是父类类型的对象"不能真的是父类对象
 * 而是真的能够做"子类对象事情"的子类对象(或者子类对象的子类对象)
 *
 *
 * 父类引用指向的真实对象的类型，就是要强转成的子类类型的对象或者子类对象。
 * 引用所指向的真实对象，必须是强转后的引用能够指向的对象。所以可以是强转后的引用的类型的对象或者子类对象
 *
 * 强转要想成功,说明原本就是父类引用指向子类对象,相当于只是还原子类对象的功能
 * 并不是真的把父类对象,当成子类对象去使用(这一条是做不到的,就会运行失败,抛出异常)
 *
 * @since 11:29
 * @author wuguidong@cskaoyan.onaliyun.com
 */
public class Demo {
    public static void main(String[] args) {
        /*Grandfather gf = new Grandfather();
        Grandfather gf2 = new Father();
        // Father f2 = (Father) gf;
        Father f3 = (Father) gf2;
        Father f = new Father();*/

        Father2 f = new Father2();
        Father f2 = new Father();
        // Son2 f21 = (Son2) f2;
        Father f3 = new Son2();
        Son2 s = (Son2) f3;

        Father f4 = new Grandson();
        // 找回了一点力量
        Son s2 = (Son) f4;
        // 做回了自己,回归了最强大的状态
        Grandson gs = (Grandson) f4;
        Son2 s3 = (Son2) f4;
    }
}
class Grandfather{}
class Father extends Grandfather{}
class Father2 extends Grandfather{}
class Son extends Father{}
class Son2 extends Father{}
class Grandson extends Son{}